/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlaufgabe4;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Liest eine uebergebene Datei ein und parsed diese. Dabei werden entsprechende
 * Daten herausgefiltert und gespeichert.
 * 
 * @author Adrian Cieluch
 */
public class CatalogParser {
    /**
     * Speichert Buecher.
     */
    private ArrayList<Book> books;
    /**
     * Speichert DVDs.
     */
    private ArrayList<DVD> dvds;
    /**
     * Speichert Tontraeger.
     */
    private ArrayList<SoundStorage> storages;
    /**
     * Speichert eBooks.
     */
    private ArrayList<EBook> eBooks;
    /**
     * Speichert den Dateipfad und Namen.
     */
    private String file;
    /**
     * Speichert die Anzahl der verworfenen Datensaetze.
     */
    private int[] discarded;
    
    /**
     * Intialisiert die Attribute mit den uebergebenen Parametern.
     * 
     * @param file Dateipfad
     * @param books BuecherListe
     * @param dvds DVDListe
     * @param soundStorages TontraegerListe
     * @param ebooks eBookListe
     */
    public CatalogParser(String file, ArrayList<Book> books, ArrayList<DVD> dvds,
            ArrayList<SoundStorage> soundStorages, ArrayList<EBook> ebooks) {
        this.file = file;
        this.books = books;
        this.dvds = dvds;
        this.storages = soundStorages;
        this.eBooks = ebooks;
        discarded = new int[4];
    }
    
    /**
     * Liest eine Datei ein, parsed diese und speichert wichtige Daten.
     */
    public void parseFile() {
        try {
            BufferedReader parser = new BufferedReader(new FileReader(file));
            String zeile = null;
            Book book = new Book();
            DVD dvd = new DVD();
            SoundStorage soundStorage = new SoundStorage();
            EBook eBook = new EBook();
            int fall = -1;
            
            while((zeile = parser.readLine()) != null) {
                if(zeile.equals("[DVD]"))
                    fall = 0;
                if(zeile.equals("[Tontraeger]"))
                    fall = 1;
                if(zeile.equals("[eBook]"))
                    fall = 2;
                if(zeile.equals("[Buch]"))
                    fall = 3;
                
                switch(fall) {
                    case 0:
                        if(!isStartingEntry(zeile)) {
                            if(!zeile.isEmpty()) {
                                addDVDInfo(dvd, zeile);
                            } else {
                                if(dvd.getEmptySlotCount() < 4) {
                                    dvds.add(dvd);
                                } else {
                                    getDiscarded()[fall]++;
                                }
                                
                                dvd = new DVD();
                            }
                        }
                        break;
                    case 1:
                        if(!isStartingEntry(zeile)) {
                            if(!zeile.isEmpty()) {
                                addSoundStorageInfo(soundStorage, zeile);
                            } else {
                                if(soundStorage.getEmptySlotCount() < 4) {
                                    storages.add(soundStorage);
                                } else {
                                    getDiscarded()[fall]++;
                                }
                                
                                soundStorage = new SoundStorage();
                            }
                        }
                        break;
                    case 2:
                        if(!isStartingEntry(zeile)) {
                            if(!zeile.isEmpty()) {
                                addEBookInfo(eBook, zeile);
                            } else {
                                if(eBook.getEmptySlotCount() < 4) {
                                    eBooks.add(eBook);
                                } else {
                                    getDiscarded()[fall]++;
                                }
                                
                                eBook = new EBook();
                            }
                        }
                        break;
                    case 3:
                        if(!isStartingEntry(zeile)) {
                            if(!zeile.isEmpty()) {
                                addBookInfo(book, zeile);
                            } else {
                                if(book.getEmptySlotCount() < 4) {
                                    books.add(book);
                                } else {
                                    getDiscarded()[fall]++;
                                }
                                
                                book = new Book();
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            
        } catch (IOException ex) {
            Logger.getLogger(CatalogParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * Prueft ob die eingelesene Zeile eine Startzeile ist und gibt das Ergebnis zurueck.
     * 
     * @param zeile Eingelesene Zeile
     * @return Startzeile true/false
     */
    private boolean isStartingEntry(String zeile) {
        boolean isStartingEntry = false;
        
        if(zeile.equals("[DVD]") || zeile.equals("[Tontraeger]") || zeile.equals("[eBook]") || zeile.equals("[Buch]"))
            isStartingEntry = true;
        
        return isStartingEntry;
    }
    
    /**
     * Fuegt einem DVD Objekt bei Uebereinstimmung mit der aus dem String gefilterten
     * Daten Attribute hinzu.
     * 
     * @param data DVD Objekt
     * @param zeile Eingelesene Zeile
     */
    private void addDVDInfo(DVD data, String zeile) {
        String[] parts = zeile.split("=");

        if(parts.length >= 2) {
            parts[1] = parts[1].replace("&", "&amp;");
            parts[1] = parts[1].replace(">", "&gt;");
            parts[1] = parts[1].replace("<", "&lt;");
            parts[1] = parts[1].replace("\"", "&quot;");
            parts[1] = parts[1].replace("'", "&apos;");
            
            if(parts[0].equals("titel"))
                data.setTitle(parts[1]);

            if(parts[0].equals("ean"))
                data.setEan(parts[1]);

            if(parts[0].equals("veroeffentlicht"))
                data.setPublished(parts[1]);

            if(parts[0].equals("studio"))
                data.setStudio(parts[1]);

            if(parts[0].equals("regisseur"))
                data.addDirector(parts[1]);

            if(parts[0].equals("schauspieler"))
                data.addActor(parts[1]);

            if(parts[0].equals("format"))
                data.addFormat(parts[1]);

            if(parts[0].equals("dimension"))
                data.setDimension(parts[1]);
        }

    }
    
    /**
     * Fuegt einem Tontraeger Objekt bei Uebereinstimmung mit der aus dem String gefilterten
     * Daten Attribute hinzu.
     * 
     * @param data Tontraeger Objekt
     * @param zeile Eingelesene Zeile
     */
    private void addSoundStorageInfo(SoundStorage data, String zeile) {
        String[] parts = zeile.split("=");

        if(parts.length >= 2) {
            parts[1] = parts[1].replace("&", "&amp;");
            parts[1] = parts[1].replace(">", "&gt;");
            parts[1] = parts[1].replace("<", "&lt;");
            parts[1] = parts[1].replace("\"", "&quot;");
            parts[1] = parts[1].replace("'", "&apos;");
            
            if(parts[0].equals("titel"))
                data.setTitle(parts[1]);

            if(parts[0].equals("ean"))
                data.setEan(parts[1]);

            if(parts[0].equals("veroeffentlicht"))
                data.setPublished(parts[1]);

            if(parts[0].equals("label"))
                data.setLabel(parts[1]);

            if(parts[0].equals("interpret"))
                data.addInterpreter(parts[1]);

            if(parts[0].equals("tontraeger"))
                data.setType(parts[1]);

            if(parts[0].equals("tontraeger_anzahl"))
                data.setAmount(parts[1]);
        }
    }

    /**
     * Fuegt einem eBook Objekt bei Uebereinstimmung mit der aus dem String gefilterten
     * Daten Attribute hinzu.
     * 
     * @param data eBook Objekt
     * @param zeile Eingelesene Zeile
     */
    private void addEBookInfo(EBook data, String zeile) {
        String[] parts = zeile.split("=");
        
        if(parts.length >= 2) {
            parts[1] = parts[1].replace("&", "&amp;");
            parts[1] = parts[1].replace(">", "&gt;");
            parts[1] = parts[1].replace("<", "&lt;");
            parts[1] = parts[1].replace("\"", "&quot;");
            parts[1] = parts[1].replace("'", "&apos;");
            
            if(parts[0].equals("titel"))
                data.addTitle(parts[1]);
            
            if(parts[0].equals("autor"))
                data.addAuthor(parts[1]);
            
            if(parts[0].equals("verlag"))
                data.setPublisher(parts[1]);

            if(parts[0].equals("veroeffentlicht"))
                data.setPublished(parts[1]);
            
            if(parts[0].equals("titel_lang"))
                data.setLongTitle(parts[1]);
            
            if(parts[0].equals("sprache"))
                data.setLanguage(parts[1]);
            
            if(parts[0].equals("inhalt"))
                data.addContent(parts[1]);
        }

    }
    
    /**
     * Fuegt einem Book Objekt bei Uebereinstimmung mit der aus dem String gefilterten
     * Daten Attribute hinzu.
     * 
     * @param data Book Objekt
     * @param zeile Eingelesene Zeile
     */
    private void addBookInfo(Book data, String zeile) {
        String[] parts = zeile.split("=");
        
        if(parts.length >= 2) {
            parts[1] = parts[1].replace("&", "&amp;");
            parts[1] = parts[1].replace(">", "&gt;");
            parts[1] = parts[1].replace("<", "&lt;");
            parts[1] = parts[1].replace("\"", "&quot;");
            parts[1] = parts[1].replace("'", "&apos;");
            
            if(parts[0].equals("titel"))
                data.setTitle(parts[1]);

            if(parts[0].equals("ean"))
                data.setEan(parts[1]);

            if(parts[0].equals("veroeffentlicht"))
                data.setPublished(parts[1]);

            if(parts[0].equals("verlag"))
                data.setPublisher(parts[1]);

            if(parts[0].equals("autor"))
                data.addAuthor(parts[1]);

            if(parts[0].equals("isbn"))
                data.setIsbn(parts[1]);

            if(parts[0].equals("bindung"))
                data.setBinding(parts[1]);

            if(parts[0].equals("edition"))
                data.setEdition(parts[1]);

            if(parts[0].equals("seiten"))
                data.setPages(parts[1]);
        }
    }

    /**
     * Gibt die verworfenen Datensaetze zurueck.
     * 
     * @return Verworfene Datensaetze
     */
    public int[] getDiscarded() {
        return discarded;
    }
}
